package com.dave.gd.common.util.xml.model;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import org.dom4j.Element;

import com.dave.gd.common.util.ReflectUtil;

/**
 * 用于去重的MapList
 * 
 * 
 * @param <T>
 */
public class XmlUnionMap<T extends XmlUnionBean> implements XmlCapacity {
    private static final long serialVersionUID = 7395401239651904869L;
    private Class<T> xmlUnionBeanCls;// 容器装载的XmlUnionBean类
    private Map<Object, T> objMap;// 用Map容器装载
    
    /**
     * 构造
     * 
     * @param xmlUnionBeanCls
     *            容器装载的XmlUnionBean类
     */
    public XmlUnionMap() {
        this(null);
    }
    
    /**
     * 构造
     * 
     * @param xmlUnionBeanCls
     *            容器装载的XmlUnionBean类
     */
    public XmlUnionMap(Class<T> xmlUnionBeanCls) {
        this.xmlUnionBeanCls = xmlUnionBeanCls;
        this.objMap = new LinkedHashMap<Object, T>();
    }
    
    /**
     * (non-Javadoc)
     * 
     */
    @Override
    public XmlCapacity newInstance() {
        return new XmlUnionMap<T>(xmlUnionBeanCls);
    }
    
    public Class<T> getXmlUnionBeanCls() {
        return xmlUnionBeanCls;
    }
    
    /**
     * 实例化节点对象
     * 
     * @return XmlUnionBean节点对象
     */
    @SuppressWarnings("unchecked")
    private T newEleInstance() {
        return (T) ReflectUtil.newInstance(xmlUnionBeanCls);
    }
    
    /**
     * (non-Javadoc)
     * 
     */
    @Override
    public void serialize(Element parentEle, String localName) {
        for (T bean : objMap.values()) {
            if (bean == null) {
                continue;
            }
            parentEle.add(bean.serialize(localName));
        }
    }
    
    /**
     * (non-Javadoc)
     * 
     */
    @Override
    public void unserialize(Element localEle) {
        if (localEle == null
            || !(localEle.elementIterator().hasNext() || localEle.attributeIterator().hasNext())) {
            // 没子节点也没属性
            return;
        }
        
        T bean = newEleInstance();
        bean.unserialize(localEle);
        this.add(bean);
    }
    
    /**
     * 增加XmlUnionBean节点：若已存在旧节点就将新节点信息合并到旧节点，否则新增节点
     * 
     * @param e
     *            XmlUnionBean节点元素
     * @return 是否成功
     */
    @SuppressWarnings("unchecked")
    public boolean add(T e) {
        if (e == null) {
            return false;
        }
        if (xmlUnionBeanCls == null) {
            xmlUnionBeanCls = (Class<T>) e.getClass();
        }
        
        T old = objMap.get(e.toKey());
        if (old != null) {
            old.merge(e);
            return false;
        }
        objMap.put(e.toKey(), e);
        return true;
    }
    
    /**
     * 将list容器的XmlUnionBean节点增加到容器里:若已存在旧节点就将新节点信息合并到旧节点，否则新增节点
     * 
     * @param list
     *            XmlUnionBean的list容器
     */
    public void addAll(Collection<T> list) {
        if (list != null) {
            for (T e : list) {
                add(e);
            }
        }
    }
    
    /**
     * 将list容器的XmlUnionBean节点增加到容器里
     * 
     * @param list
     *            XmlUnionBean的XmlUnionMap容器
     */
    public void addAll(XmlUnionMap<T> list) {
        if (list != null) {
            for (T e : list.getAll()) {
                add(e);
            }
        }
    }
    
    /**
     * 根据Key键值获取XmlUnionBean节点元素
     * 
     * @param key
     *            键值
     * @return XmlUnionBean节点元素
     */
    public T get(Object key) {
        return objMap.get(key);
    }
    
    /**
     * 获取所有XmlUnionBean节点元素
     * 
     * @return XmlUnionBean节点元素(Collection)
     */
    public Collection<T> getAll() {
        return objMap.values();
    }
    
    /**
     * 清空容器
     */
    public void clear() {
        objMap.clear();
    }
    
    /**
     * 判断容器是否为空
     * 
     * @return 如容器空返回true，否则返回false
     */
    public boolean isEmpty() {
        return objMap.isEmpty();
    }
    
    /**
     * 判断容器是否非空
     * 
     * @return 如容器非空返回true，否则返回false
     */
    public boolean isNotEmpty() {
        return !objMap.isEmpty();
    }
    
    /**
     * 获取容器节点个数
     * 
     * @return 节点个数
     */
    public int size() {
        return objMap.size();
    }
    
    /**
     * 删除某个XmlUnionBean节点元素
     * 
     * @param e
     *            XmlUnionBean节点元素
     */
    public void remove(T e) {
        objMap.remove(e.toKey());
    }
    
    /**
     * 根据key键值删除XmlUnionBean节点元素
     * 
     * @param key
     *            键值
     */
    public void remove(Object key) {
        objMap.remove(key);
    }
    
    /**
     * 若节点键值不存在就增加到容器里
     * 
     * @param e
     *            XmlUnionBean节点元素
     */
    @SuppressWarnings("unchecked")
    public void addIfNotExists(T e) {
        if (e == null) {
            return;
        }
        if (xmlUnionBeanCls == null) {
            xmlUnionBeanCls = (Class<T>) e.getClass();
        }
        
        if (!objMap.containsKey(e.toKey())) {
            objMap.put(e.toKey(), e);
        }
    }
    
    /**
     * 若list里节点键值在容器里不存在就将此节点增加到容器里
     * 
     * @param list
     *            XmlUnionBean的Collection容器
     */
    public void addIfNotExists(Collection<T> list) {
        if (list != null) {
            for (T e : list) {
                addIfNotExists(e);
            }
        }
    }
    
    /**
     * 若list里节点键值在容器里不存在就将此节点增加到容器里
     * 
     * @param list
     *            XmlUnionBean的XmlUnionMap容器
     */
    public void addIfNotExists(XmlUnionMap<T> list) {
        if (list != null) {
            for (T e : list.getAll()) {
                addIfNotExists(e);
            }
        }
    }
    
}
